package com.xunyi.learndemo.service;

import com.xunyi.learndemo.domain.OrderInfo;
import com.xunyi.learndemo.mapper.OrderInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;

@Service
public class OrderService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    // 定义订单超时时间，例如：30分钟
    public static final Duration ORDER_TIMEOUT = Duration.ofMinutes(30);

    /**
     * 定时任务：每分钟检查并取消超时未支付的订单。
     */
    @Scheduled(fixedRate = 60000)  // 每分钟执行一次
    public void cancelUnpaidOrders() {
        System.out.println("start scanner cancelUnpaidOrders");
        int page = 0;
        int size = 100;  // 每页处理100条订单，具体大小可根据实际情况调整
        List<OrderInfo> unpaidOrdersPage;

        do {
            unpaidOrdersPage = getUnpaidOrders(page, size);
            unpaidOrdersPage.forEach(order -> {
                if (isOrderTimedOut(order)) {
                    order.setOrderStatus(OrderStatus.CANCELED.name());
                    orderInfoMapper.updateOrderInfo(order);
                }
            });
            page++;
        } while (unpaidOrdersPage.size() == size);
    }

    /**
     * 分页获取超时未支付的订单。
     *
     * @param page 页码
     * @param size 每页大小
     * @return 分页后的未支付订单
     */
    private List<OrderInfo> getUnpaidOrders(int page, int size) {
        LocalDateTime timeoutThreshold = LocalDateTime.now().minus(ORDER_TIMEOUT);
        Date createTime = convertToDate(timeoutThreshold);
        int offset = page * size;
        return orderInfoMapper.findUnpaidOrders(OrderStatus.UNPAID.name(), createTime, offset, size);
    }

    public Date convertToDate(LocalDateTime localDateTime) {
        // 1. 将 LocalDateTime 转换为 Instant
        Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();

        // 2. 使用 Instant 创建 Date 对象
        return Date.from(instant);
    }

    /**
     * 判断订单是否超时。
     *
     * @param order 订单对象
     * @return true 如果订单已超时，否则 false
     */
    private boolean isOrderTimedOut(OrderInfo order) {
        // 1. 将 Date 转换为 Instant
        Instant instant = order.getCreateTime().toInstant();

        // 2. 使用 Instant 和系统默认时区创建 LocalDateTime
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

        return LocalDateTime.now().isAfter(localDateTime.plus(ORDER_TIMEOUT));
    }

    public enum OrderStatus {
        UNPAID,    // 订单已创建，但尚未支付
        PAID,      // 订单已支付
        SHIPPED,   // 订单已发货
        COMPLETED, // 订单已完成
        CANCELED,  // 订单已取消
        REFUNDED   // 订单已退款
    }
}
